#pragma once
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <sys/uio.h>
#include <string.h>
#include <unistd.h>
#include <strings.h>
#include <bits/socket.h>
#include <sys/socket.h>


using namespace std;
class Buffer
{
public:
  Buffer(int size)
  : m_capacity(size)
  {
      m_data = (char *)malloc(size);
      bzero(m_data, size);//把内存中的数据初始化为0
  }
  
  ~Buffer()
  {
    if (m_data != nullptr)
    {
        free(m_data);
    }
}

  // 扩容
  void extendRoom(int size)
  {
    // 内存够用
    if (writeableSize() >= size)
    {
        return;
    }
    // 内存需要合并
    // 剩余内存+已读内存
    else if (m_readPos + writeableSize() >= size)
    {
        // 获取未读内存的大小
        int readable = readableSize();
        // 移动内存
        memcpy(m_data, m_data + m_readPos, readable);
        // 更新位置
        m_readPos = 0;
        m_writePos = readable;
    }
    // 内存不够，需要扩容
    else
    {
        void *temp = realloc(m_data, m_capacity + size);
        if (temp == nullptr)
        {
            return;
        }
        memset((char*)temp + m_capacity, 0, size);
        // 更新数据
        m_data = static_cast<char *>(temp);
        m_capacity += size;
    }
}
  // 获取剩余可读容量
  inline int readableSize()
  {
    return m_writePos-m_readPos;
  }
  // 获取剩余可写的内存容量
  inline int writeableSize()
  {
    return m_capacity-m_writePos;
  }
  // 写内存   1.直接写2.接收套接字的数据
  int appendString(const char *data, int size)
  {
    if (data == nullptr || size <= 0)
    {
        return -1;
    }
    // 扩容
    extendRoom(size);
    // 数据拷贝
    memcpy(m_data + m_writePos, data, size);
    m_writePos += size;
    return 0;
}

  int appendString(const char *data)
  {
    int size = strlen(data);
    int ret = appendString(data, size);
    return ret;
}

 int appendString(const string data)
 {
  int ret =appendString(data.data());
  return ret;
}

  int socktRead(int fd)
  {

    // read/recv/readv
    struct iovec vec[2];
    //初始化数组元素
    int writeable = writeableSize();
    vec[0].iov_base = m_data + m_writePos;
    vec[0].iov_len = writeable;
    char *tmpbuf = (char *)malloc(40960);
    vec[1].iov_base = tmpbuf;
    vec[1].iov_len = 40960;
    int result = readv(fd, vec, 2);
    if (result == -1)
    {
        return -1;
    }
    else if (result <= writeable)
    {
        m_writePos += result;
    }
    else
    {
        m_writePos = m_capacity;
        appendString(tmpbuf, result - writeable);
    }
    free(tmpbuf);
    return result;
}


  // 根据\r\n取出一行，找到其在数据块中的位置，返回该位置
  char *findCRLE()
  {
    char *ptr =static_cast<char*>( memmem(m_data + m_readPos, readableSize(), "\r\n", 2));
    return ptr;
}

  // 发送数据
  int sendData(int socket)
  {
    // 判断有无数据
   int readable = readableSize();
   // 判断有多少未读的数据，这些未读的数据就是待发送的数据
   if (readable > 0)
   {
       int count = send(socket, m_data + m_readPos, readable, MSG_NOSIGNAL);
       if (count)
       {
          m_readPos += count;
           usleep(1);
       }
       return count;
   }
   return 0;
}
//得到读数据的 起始位置
inline char* data()
{
  return m_data+m_readPos;
}
inline int readPosIncrease(int count)
{
  m_readPos +=count;
  return m_readPos;
}
private:
  char *m_data;
  int m_capacity;
  int m_readPos;
  int m_writePos;
};
